package com.haizhi.controller;

import com.haizhi.storage.*;
import com.haizhi.util.Tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;

@Controller
public class FileController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private final StorageService storageService;

    @Autowired
    public FileController(StorageService storageService) {
        this.storageService = storageService;
        // 启动时 初始化目录信息
        this.storageService.storageInit();
    }

    @RequestMapping(method = RequestMethod.GET, value = "/")
    public String listDownloadedFiles(Model model) throws IOException {

        model.addAttribute("down_files", storageService.loadAllDownload()
                .map(Path::toString)
                .collect(Collectors.toList()));

        model.addAttribute("up_files", storageService.loadAllUpload(1)
                .map(Path::toString)
                .collect(Collectors.toList()));

        logger.info("请求首页....");
        return "index";
    }

    @RequestMapping(method = RequestMethod.GET, value = "/list")
    @ResponseBody
    public List<String> getDownloadedList() throws IOException {
        logger.info("请求/list");
        return storageService.loadAllDownload().filter(storageService::md5InMap).map(path -> Tools.stringToBase64(path.toString()))
                .collect(Collectors.toList());
    }

    @RequestMapping(method = RequestMethod.GET, value = "/download/{base64:.+}")
    @ResponseBody
    public void downloadFile(@PathVariable String base64,
                             HttpServletResponse response,
                             HttpServletRequest request) {
        String filename = Tools.base64ToString(base64);
        storageService.loadDownAsResource(filename, response, request);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/md5/{base64}")
    @ResponseBody
    public String getFileMD5(@PathVariable String base64) {
        String filename = Tools.base64ToString(base64);
        logger.info("请求MD5 file = {}", filename);
        return storageService.getDownFileMD5(filename);
    }

    @RequestMapping(method = RequestMethod.POST, value = "/front_upload")
    public String fileFrontUpload(@RequestParam("file") MultipartFile file,
                                  RedirectAttributes redirectAttributes,
                                  HttpServletRequest request) {
        try {
            if (storageService.storeUpload(file, file.getOriginalFilename(), request)) {
                redirectAttributes.addFlashAttribute("message",
                        "You successfully uploaded " + file.getOriginalFilename() + "!");
            } else {
                redirectAttributes.addFlashAttribute("message",
                        "You uploaded " + file.getOriginalFilename() + " fail !");
            }
        } catch (StorageException e) {
            logger.warn("空文件...");
            return "redirect:/";
        }

        logger.info("请求/front_upload");
        return "redirect:/";
    }

    @RequestMapping(method = RequestMethod.POST, value = "/upload/{base64}")
    @ResponseBody
    public String fileUpload(@RequestParam("file") MultipartFile multipartFile,
                             @PathVariable String base64,
                             HttpServletRequest request) {
        try {
            String filepath = Tools.base64ToString(base64);
            logger.info("后台上传: filepath = {}", filepath);
            if (storageService.storeUpload(multipartFile, filepath, request)) {
                return "success";
            }
            return "fail";
        } catch (StorageFileEmptyException e) {
            logger.warn("空文件...");
        } catch (StorageIOException e) {
            logger.error("ERROR:", e);
            return "fail";
        }
        return "success";
    }

    @ExceptionHandler(StorageFileNotFoundException.class)
    public ResponseEntity handleStorageFileNotFound() {
        return ResponseEntity.notFound().build();
    }

}
